<template></template>
<script lang="ts">

import * as THREE from 'three';
import { OrbitControls } from 'three/examples/jsm/Addons.js';

// 初始化基础场景
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.set(0, 2, 5);

const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 控制器
const controls = new OrbitControls(camera, renderer.domElement);
controls.enableDamping = true;

// 几何体：一个细长的矩形，作为“手臂”
const geometry = new THREE.CylinderGeometry(0.2, 0.2, 4, 8, 8, true); // 长条形
geometry.translate(0, 2, 0); // 向上平移，使骨骼从底部开始作用

// 创建两个骨骼：肩膀 -> 前臂
const bone1 = new THREE.Bone();
bone1.position.y = 0;

const bone2 = new THREE.Bone();
bone2.position.y =2;
bone1.add(bone2);

// 创建骨架
const skeleton = new THREE.Skeleton([bone1, bone2]);

// 创建蒙皮网格
const material = new THREE.MeshStandardMaterial({
  color: 0x00ccff,
  side: THREE.DoubleSide,
});

const mesh = new THREE.SkinnedMesh(geometry, material);
mesh.add(bone1);               // 将骨骼添加到网格中
mesh.bind(skeleton);           // 绑定骨架

scene.add(mesh);

// 骨骼权重设置：手动设置骨骼对顶点的影响
const position = geometry.attributes.position;
const skinIndices = [];
const skinWeights = [];

for (let i = 0; i < position.count; i++) {
  const y = position.getY(i);

  if (y < 2) {
    // 下半部分由骨骼1影响
    skinIndices.push(0, 0, 0, 0);
    skinWeights.push(1, 0, 0, 0);
  } else {
    // 上半部分由骨骼2影响
    skinIndices.push(1, 0, 0, 0);
    skinWeights.push(1, 0, 0, 0);
  }
}

geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4));
geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4));

// 灯光
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 10, 7.5);
scene.add(light);

// 动画：旋转骨骼2（前臂）
let angle = 0;
function animate() {
  requestAnimationFrame(animate);
  angle += 0.02;
  bone2.rotation.z = Math.sin(angle) * 0.5; // 摆动手臂

  controls.update();
  renderer.render(scene, camera);
}
animate();

</script>